﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Blackbird.Studio.Control {
    /// <summary>
    /// Interaction logic for ImageGrid.xaml
    /// </summary>
    public partial class ImageGrid {

        public int ActiveImageIndex { get; set; }
        public int SelectedImageIndex { get; set; }

        public ImageSource ActiveImageSource { get; set; }
        public ImageSource SelectedImageSource { get; set; }

        public Image ActiveImage { get; set; }
        public Image SelectedImage { get; set; }
        public ImageGrid() {
            InitializeComponent();
            ActiveImageRectangle = new Rectangle
                                       {
                                           Fill =
                                               new SolidColorBrush(Color.FromArgb(64, 255,
                                                                                  255, 255))
                                       };

            ConfigureRowsAndColumns();
        }

        public void ConfigureRowsAndColumns() {

            if (ImageSources != null) {
                GridCanvas.Children.Clear();

                GridCanvas.Width = MapWidth * CellWidth * Zoom;
                GridCanvas.Height = MapHeight * CellHeight * Zoom;
                var xFactor = CellWidth * Zoom;
                var yFactor = CellHeight * Zoom;

                var sources = ImageSources.ToArray();
                var imageCount = sources.Count();

                for (var y = 0; y < MapHeight; y++) {
                    for (var x = 0; x < MapWidth; x++) {
                        
                        var index = (y * MapWidth) + x;
                        if (index >= imageCount) continue;

                        var source = sources[index];

                        var image = new Image {
                            Source = source,
                            Opacity = (index == SelectedImageIndex) ? 0.4 : 1.0,
                            Width = CellWidth * Zoom,
                            Height = CellHeight * Zoom                            
                        };
                        
                        if(index == SelectedImageIndex)
                        {
                            SelectedImage = image;
                        }
                        
                        GridCanvas.Children.Add(image);
                        
                        var x1 = (x * xFactor);
                        var y1 = (y * yFactor);
                        
                        Canvas.SetTop(image, y1);
                        Canvas.SetLeft(image, x1);

                        if ((ActiveImage != null) && (ActiveImage == image))
                        {
                            GridCanvas.Children.Add(ActiveImageRectangle);
                            Canvas.SetTop(ActiveImageRectangle, y1);
                            Canvas.SetLeft(ActiveImageRectangle, x1);
                        }
                    }
                }
            }
        }

        public static void OnPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) {
            var control = (source as ImageGrid);
            if (control != null) {
                control.ConfigureRowsAndColumns();
            }
        }

        #region CellWidth Dependency Property

        public static readonly DependencyProperty CellWidthProperty = DependencyProperty.Register(
                "CellWidth",
                typeof(double),
                typeof(ImageGrid),
                new FrameworkPropertyMetadata(64.0, OnPropertyChanged)
            );

        public double CellWidth {
            get { return (double)GetValue(CellWidthProperty); }
            set { SetValue(CellWidthProperty, value); }
        }

        #endregion

        #region CellHeight Dependency Property

        public static readonly DependencyProperty CellHeightProperty = DependencyProperty.Register(
                "CellHeight",
                typeof(double),
                typeof(ImageGrid),
                new FrameworkPropertyMetadata(64.0, OnPropertyChanged)
            );

        public double CellHeight {
            get { return (double)GetValue(CellHeightProperty); }
            set { SetValue(CellHeightProperty, value); }
        }

        #endregion

        #region MapWidth Dependency Property

        public static readonly DependencyProperty MapWidthProperty = DependencyProperty.Register(
                "MapWidth",
                typeof(int),
                typeof(ImageGrid),
                new UIPropertyMetadata(3, OnPropertyChanged)
            );

        public int MapWidth {
            get { return (int)GetValue(MapWidthProperty); }
            set { SetValue(MapWidthProperty, value); }
        }

        #endregion

        #region MapHeight Dependency Property

        public static readonly DependencyProperty MapHeightProperty = DependencyProperty.Register(
                "MapHeight",
                typeof(int),
                typeof(ImageGrid),
                new FrameworkPropertyMetadata(3, OnPropertyChanged)
            );

        public int MapHeight {
            get { return (int)GetValue(MapHeightProperty); }
            set { SetValue(MapHeightProperty, value); }
        }

        #endregion

        #region Zoom Property

        // Using a DependencyProperty as the backing store for Zoom.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ZoomProperty = DependencyProperty.Register(
                "Zoom",
                typeof(double),
                typeof(ImageGrid),
                new FrameworkPropertyMetadata(1.0, OnPropertyChanged)
            );

        public double Zoom {
            get { return (double)GetValue(ZoomProperty); }
            set { SetValue(ZoomProperty, value); }
        }

        #endregion

        #region ImageSources Property

        public static readonly DependencyProperty ImageSourcesProperty = DependencyProperty.Register(
            "ImageSources",
            typeof(IEnumerable<ImageSource>),
            typeof(ImageGrid),
            new FrameworkPropertyMetadata(OnPropertyChanged));

        public IEnumerable<ImageSource> ImageSources {
            get { return (IEnumerable<ImageSource>)GetValue(ImageSourcesProperty); }
            set { SetValue(ImageSourcesProperty, value); }
        }


        #endregion

        #region ActiveImageRectangle


        public Rectangle ActiveImageRectangle {
            get { return (Rectangle)GetValue(ActiveImageRectangleProperty); }
            set { SetValue(ActiveImageRectangleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ActiveImageRectangle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ActiveImageRectangleProperty =
            DependencyProperty.Register("ActiveImageRectangle", typeof (Rectangle), typeof (ImageGrid),
                                        new UIPropertyMetadata(OnPropertyChanged));        
        #endregion

        #region Mouse Handling

        private void RootGridMouseWheel(object sender, MouseWheelEventArgs e) {

            var deltaPercent = (e.Delta / 10000.0);
            var newValue = Zoom + deltaPercent;
            if ((newValue < 10) && (newValue > 0.1)) {
                Zoom = newValue;
            }
        }

        private void RootGridMouseMove(object sender, MouseEventArgs e) {
            var position = e.GetPosition(GridCanvas);
            var xFactor = CellWidth * Zoom;
            var yFactor = CellHeight * Zoom;
            var x = (int)(position.X / xFactor);
            var y = (int)(position.Y / yFactor);
            var imageIndex = (y * MapWidth) + x;
            if (imageIndex != SelectedImageIndex) {
                SelectedImageIndex = imageIndex;
                if (ImageSources != null) {
                    SelectedImageSource = ImageSources.ToArray()[SelectedImageIndex];
                    ConfigureRowsAndColumns();
                }
            }
        }

        private void RootGridMouseClick(object sender, MouseButtonEventArgs e)
        {
            var position = e.GetPosition(GridCanvas);
            var xFactor = CellWidth * Zoom;
            var yFactor = CellHeight * Zoom;
            var x = (int)(position.X / xFactor);
            var y = (int)(position.Y / yFactor);
            var imageIndex = (y * MapWidth) + x;
            if(imageIndex != ActiveImageIndex)
            {
                ActiveImageIndex = imageIndex;
                if(ImageSources != null)
                {
                    ActiveImageSource = ImageSources.ToArray()[ActiveImageIndex];
                    ConfigureRowsAndColumns();
                }
            }
        }

        #endregion

    }
}